package sr.logger;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;

import org.joda.time.DateTime;



public class Logger {
	private String className;
	private static long counter = 0;
	private static HashMap<String, Logger> loggers = new HashMap<String, Logger>();
	private static Object lock = new Object();
	private static BufferedWriter writer;
	static
	{
		try {
			writer = new BufferedWriter(new FileWriter("Log.txt"));
		} catch (IOException e) {
			
			e.printStackTrace();
		}
		Runtime.getRuntime().addShutdownHook(new Thread() 
		{
			@Override
			public void run()
			{
				try {
					writer.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
				);
	}
	private Logger(String className)
	{
		this.className = className;
	}
	private static Logger createLogger(Class<?> clazz)
	{
		Logger newLogger = new Logger(clazz.getName());
		loggers.put(clazz.getName(), newLogger);
		return newLogger;
	}
	public synchronized static Logger getLogger(Class<?> clazz)
	{
		Logger logger = loggers.get(clazz.getName());
		if(logger == null)
		{
			logger = createLogger(clazz);
		}
		return logger;
	}	
	private String prepareMessage(String methodName, String additionalArguments)
	{
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		sb.append(new Date());
		sb.append(",tick: ");
		sb.append(counter + "][");
		sb.append(className + "][");
		sb.append(methodName + "]");
		if(additionalArguments != "")
			sb.append("[" + additionalArguments + "]");
		sb.append("\r\n");
		return sb.toString();
	}
	public long log(String methodName, String additionalArguments)
	{
		if(additionalArguments == null)
			additionalArguments = "";
		synchronized(lock)
		{
			String message = prepareMessage(methodName,additionalArguments);
			try {
				writer.write(message);
				writer.flush();
			} catch (IOException e) 
			{
				e.printStackTrace();
			}
			++counter;
		}
		return counter;
	}
	public long log(String methodName)
	{
		return log(methodName, "");
	}
	public long log(long remoteCounter,String methodName)
	{
		return log(remoteCounter,methodName, "");
	}
	public long log(long remoteCounter,String methodName,String additionalArguments)
	{
		synchronized(lock)
		{
			if(counter < remoteCounter)
				counter = remoteCounter;
			
		}
		return log(methodName, additionalArguments);
	}
}
